package util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;

import adt.Sentence;
import adt.Word;

/**
 * An iterator to iterate all the sentences denoted by a file list path.
 * 
 * 用于迭代所有句子的迭代器。存储句子的各个文件由一个指定的文件列表写明。
 * 
 * @author Tianyu Xu
 * 
 */
public class SentenceIterator implements Enumeration<Sentence> {

	private BufferedReader r = null;
	private ArrayList<File> fileList = null;
	private ArrayList<Sentence> sentenceList = null;
	private int pointer;

	public SentenceIterator(String fileListPath) {
		fileList = new ArrayList<File>();
		sentenceList = new ArrayList<Sentence>();
		pointer = 0;
		String s;

		// read in the file list
		// 读取文件列表
		try {
			r = new BufferedReader(new InputStreamReader(new FileInputStream(fileListPath), "UTF8"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		try {
			s = r.readLine();
			while (s != null) {
				fileList.add(new File(s));
				s = r.readLine();
			}
			r.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		// for each file in the fileList
		// 对文件列表中的每个文件
		for (int i = 0; i < fileList.size(); i++) {
			TimeCounter time = new TimeCounter(String.format("#### Reading sentences from \"%s\" ...", fileList.get(i).getName()));

			try {
				r = new BufferedReader(new InputStreamReader(new FileInputStream(fileList.get(i)), "UTF8"));

				// 跳过第一个数字
				r.readLine();

				s = r.readLine();
				Sentence t = null;

				while (s != null) {
					// if there is a blank line
					// 如果遇到了空行
					if (s.equals("")) {
						if (t != null) {
							// add right paddings, end the sentence
							// 添加右填充，并结束句子，将其存储
							addPaddings(t, false);
							sentenceList.add(t);
							t = null;
							// 跳过数字
							r.readLine();
							s = r.readLine();
							continue;
						} else {
							s = r.readLine();
							continue;
						}
					}
					// if should add a new character
					// 如果需要添加一个新字符
					if (t == null) {
						// construct a new sentence and add left paddings
						// 构造一个新的句子兑现，并添加左填充
						t = new Sentence();
						addPaddings(t, true);
					}
					t.addWord(new Word(s));
					s = r.readLine();
				}
				r.close();

				time.stop("#### Reading finished in %s.\n\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Add paddings to a sentence.
	 * 
	 * 向句子两端添加填充字符。
	 * 
	 * @param s
	 *            要添加填充字符的句子
	 * @param addLeft
	 *            是否向左侧添加填充字符；如果取值为 false，则为向右侧添加填充字符。
	 */
	private void addPaddings(Sentence s, boolean addLeft) {
		int i;
		if (addLeft) {
			for (i = 0; i < Params.PADDING_SIZE; i++) {
				s.addWord(new Word(Params.LEFT_PADDING_STRING));
			}
		} else {
			for (i = 0; i < Params.PADDING_SIZE; i++) {
				s.addWord(new Word(Params.RIGHT_PADDING_STRING));
			}
		}
	}

	@Override
	public boolean hasMoreElements() {
		return pointer < sentenceList.size();
	}

	@Override
	public Sentence nextElement() {
		if (!hasMoreElements())
			return null;
		else
			return sentenceList.get(pointer++);
	}

	/**
	 * 重设指针以便进行下一次迭代
	 */
	public void resetPointer() {
		pointer = 0;
	}

}
